local game = require "club.threecard.sudoku"

local M = game.ui.element()

local Candidate = game.ui.element()

function Candidate:ctor(panel, value)
    self.panel = panel
    self.value = value
end

function Candidate:on_injected(bind)
    bind("button.click", self.button, self.on_click)
end

function Candidate:on_click()
    game.audio.post("solve")
    self.panel:on_candidate_click(self)
end

function Candidate:set_marked(marked)
    self.marked_obj:SetActive(marked)
end

local function update_candidates(self, cell)
    for i, candidate in ipairs(self.candidates) do
        local marked = not not cell.candidates[i]
        candidate:set_marked(marked)
    end
end

local function unmark_all(self)
    for i, candidate in ipairs(self.candidates) do
        candidate:set_marked(false)
    end
end

M.store_watchers = {
    ingame = {
        ["$"] = function()
        end,
        ["选中格子"] = function(self, store, state, args)
            update_candidates(self, args)
        end,
        ["取消选中格子"] = function(self, store, state, args)
            unmark_all(self)
        end,
        ["标记数字变更"] = function(self, store, state, args)
            update_candidates(self, args)
        end,
        ["笔记状态变更"] = function(self, store, state, args)
            local on = args
            if on and state.selected_cell then
                update_candidates(self, state.selected_cell)
            else
                unmark_all(self)
            end
        end
    }
}

function M:ctor(parent, size)
    self.size = size
    self.parent = parent
    self.candidates = {}
    for i = 1, 9 do
        local candidate = Candidate.new(self, i)
        candidate:set_gameobject(obj, true)
        if i > size then
            candidate:hide()
        end
        table.insert(self.candidates, candidate)
    end
end

function M:on_injected(bind)
    for i = 1, 9 do
        local candidate = self.candidates[i]
        local obj = self.transform:GetChild(i - 1).gameObject
        candidate:set_gameobject(obj, true)
    end
end

function M:on_candidate_click(candidate)
    self.parent:on_candidate_click(candidate.value)
end

function M:on_release()
    for _, candidate in ipairs(self.candidates) do
        candidate:release()
    end
    self.candidates = nil
end

return M